﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="FileActioner.cs" company="DissingNelleman">
//   
// All rights reserved. </copyright>
// <summary>
//   The file actioner.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ServiceLibrary.Actioners.Base
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    using NHibernate;

    using ServiceLibrary.Models.Base;
    using ServiceLibrary.Models.Domain;
    using ServiceLibrary.Services.Commands;
    using ServiceLibrary.Services.Queries;
    using ServiceLibrary.Services.Results;

    /// <summary>
    /// The file actioner.
    /// </summary>
    public class FileActioner : ActionerBase
    {
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="FileActioner"/> class.
        /// </summary>
        /// <param name="session">
        /// The session.
        /// </param>
        /// <param name="activeUser">
        /// The active user.
        /// </param>
        public FileActioner(ISession session, User activeUser)
            : base(session, activeUser)
        {
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// The create file.
        /// </summary>
        /// <param name="newFile">
        /// The new file.
        /// </param>
        public void CreateFile(File newFile)
        {
            Data content = newFile.Content;
            this.Session.Save(content);
            newFile.Content = content;
            newFile.CreatedDateTime = DateTime.Now;

            this.Session.Save(newFile);

            this.Log.CreateLogEntry(
                newFile.ID, string.Format("Filen '{0}' blev uploadet.", newFile.Name), Enums.LogEntryType.File);
        }

        /// <summary>
        /// The create file.
        /// </summary>
        /// <param name="cmd">
        /// The cmd.
        /// </param>
        public void CreateFile(CreateFileCommand cmd)
        {
            if (cmd.NewFile != null)
            {
                var d = new Data();
                d.ID = Guid.NewGuid();
                d.Content = cmd.NewFile.ContentData;

                var newFile = new File();
                newFile.ID = cmd.NewFile.ID;
                newFile.Content = d;
                newFile.ContentType = cmd.NewFile.ContentType;
                newFile.Name = cmd.NewFile.Name;

                CreateFile(newFile);
            }
        }

        /// <summary>
        /// The delete file.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        public void DeleteFile(Guid id)
        {
            var fileToDelete = this.Session.Get<File>(id);

            if (fileToDelete != null)
            {
                Data dataToDelete = fileToDelete.Content;
                fileToDelete.Content = null;
                this.Session.Delete(dataToDelete);
                this.Session.Delete(fileToDelete);

                this.Log.CreateLogEntry(id, "Filen '{0}' blev slettet.", Enums.LogEntryType.File);
            }
        }

        /// <summary>
        /// The execute search query.
        /// </summary>
        /// <param name="query">
        /// The query.
        /// </param>
        /// <returns>
        /// The <see cref="FileResult"/>.
        /// </returns>
        public FileResult ExecuteSearchQuery(FileQuery query)
        {
            SearchSettings settings = query.Settings;

            var result = new FileResult();

            IQueryOver<File, File> search = this.Session.QueryOver<File>();
            this.ApplyDefaultCriterias(settings, search);


            List<File> s = this.Sort(settings, search.List()).ToList();

            int rowCount = search.RowCount();

            if (settings != null && settings.Skip != null && settings.Take != null && settings.Take > 0)
            {
                s = s.Skip((int)settings.Skip).Take((int)settings.Take).ToList();
            }

            result.TotalRowCount = rowCount;

            foreach (File file in s)
            {
                if (query.OnlyFileInfo)
                {
                    file.Content.Content = null;
                }
                Services.Dto.File dto = Services.Dto.File.Convert(file);
                if (dto != null)
                {
                    result.List.Add(dto);
                }
            }

            return result;
        }

        /// <summary>
        /// The get file.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="File"/>.
        /// </returns>
        public File GetFile(Guid id)
        {
            var file = this.Session.Get<File>(id);

            return file;
        }

        /// <summary>
        /// The sort.
        /// </summary>
        /// <param name="settings">
        /// The settings.
        /// </param>
        /// <param name="list">
        /// The list.
        /// </param>
        /// <returns>
        /// The ordered list of files.
        /// </returns>
        public IOrderedEnumerable<File> Sort(SearchSettings settings, IList<File> list)
        {
            bool asc = settings.SortAscending == null || (bool)settings.SortAscending;

            return asc ? list.OrderBy(x => x.Name) : list.OrderByDescending(x => x.Name);
        }

        #endregion
    }
}